<template>
  <div>
    <Card title="场景集查询" :bordered="false" :dis-hover="true">
      <div slot="extra">
        <Button
          size="small"
          type="primary"
          icon="ios-search"
          class="card-extra-item"
          @click="search"
          >查询</Button
        >
        <Button
          size="small"
          type="default"
          icon="ios-refresh"
          class="card-extra-item"
          @click="reset"
          >重置</Button
        >
        <Button
          size="small"
          type="text"
          :icon="showMore ? 'ios-arrow-up' : 'ios-arrow-down'"
          class="card-extra-item"
          @click="showMore = !showMore"
          >{{ showMore ? "收起" : "展开" }}</Button
        >
      </div>
      <Form
        inline
        label-position="right"
        :label-width="100"
        :model="searchParams"
      >
        <Row :gutter="20">
          <Col span="6">
            <FormItem label="所属项目" prop="project">
              <Select
                v-model="searchParams.project"
                filterable
                clearable
                @on-select="changeProjectOption"
                @on-clear="clearProject"
              >
                <Option
                  v-for="item in projects"
                  :value="item.id"
                  :key="item.id"
                  >{{ item.name }}</Option
                >
              </Select>
            </FormItem>
          </Col>
          <Col span="6">
            <FormItem label="场景集名称">
              <Input
                clearable
                placeholder="请输入场景集名称"
                v-model="searchParams.name"
              />
            </FormItem>
          </Col>
          <Col span="6">
            <FormItem label="测试场景">
              <Select
                v-model="searchParams.testsuite"
                :max-tag-count="1"
                clearable
                multiple
                filterable
                size="default"
              >
                <Option
                  v-for="item in testsuites"
                  :key="item.id"
                  :value="item.id"
                  :label="item.name"
                >
                  <span>{{ item.name }}</span>
                </Option>
              </Select>
            </FormItem>
          </Col>
          <Col span="6">
            <FormItem label="场景集创建人">
              <Select
                v-model="searchParams.creator"
                multiple
                filterable
                :max-tag-count="2"
              >
                <Option
                  v-for="(item, index) in users"
                  :value="item.id"
                  :label="item.real_name"
                  :key="index"
                ></Option>
              </Select>
            </FormItem>
          </Col>
        </Row>
        <CollapseTransition>
          <div v-show="showMore">
            <Row :gutter="20">
              <Col span="6">
                <FormItem label="场景集状态">
                  <Select v-model="searchParams.status" clearable>
                    <Option value="INITIAL">初始状态</Option>
                    <Option value="PASS">全部通过</Option>
                    <Option value="PARTIAL_PASS">部分通过</Option>
                    <Option value="FAIL">全部失败</Option>
                  </Select>
                </FormItem>
              </Col>
              <Col span="6">
                <FormItem label="重要级别">
                  <Select v-model="searchParams.level" multiple>
                    <Option
                      v-for="(item, index) in levels"
                      :value="item.value"
                      :label="item.label"
                      :key="index"
                    ></Option>
                  </Select>
                </FormItem>
              </Col>
            </Row>
          </div>
        </CollapseTransition>
      </Form>
    </Card>
    <Card title="场景集列表" :bordered="false" :dis-hover="true">
      <div slot="extra">
        <span class="card-extra-item">
          <Icon
            size="24"
            :color="statusColor['INITIAL']"
            type="ios-leaf"
          />初始状态
        </span>
        <span class="card-extra-item">
          <Icon
            size="24"
            :color="statusColor['PASS']"
            type="ios-leaf"
          />全部通过
        </span>
        <span class="card-extra-item">
          <Icon
            size="24"
            :color="statusColor['PARTIAL_PASS']"
            type="ios-leaf"
          />部分通过
        </span>
        <span class="card-extra-item">
          <Icon
            size="24"
            :color="statusColor['FAIL']"
            type="ios-leaf"
          />全部失败
        </span>
        <Button
          class="card-extra-item"
          size="small"
          type="primary"
          @click="createTestsuiteSet = true"
          >创建场景集</Button
        >
        <Button
          class="card-extra-item"
          size="small"
          type="primary"
          @click="handleBatchExecTestsuiteSet"
          >批量执行</Button
        >
        <Button
          class="card-extra-item"
          size="small"
          type="primary"
          @click="handleExportTestsuiteSet"
          :loading="loading"
          >导出场景集</Button
        >
        <Button
          type="primary"
          size="small"
          class="card-extra-item"
          @click="showCreatePeriodicTaskModal"
          >创建定时任务</Button
        >
        <Button
          class="card-extra-item"
          size="small"
          type="error"
          @click="showBatchDeleteTestsuiteSet"
          >删除</Button
        >
      </div>
      <Table
        :columns="testsuiteSetColumns"
        :data="testsuiteSetData"
        border
        size="small"
        :tooltip-max-width="500"
        @on-selection-change="selectionChange"
      >
        <template slot-scope="{ row }" slot="project">{{
          row.project.name
        }}</template>
        <template slot-scope="{ row }" slot="testsuites">
          <Tag
            color="blue"
            type="border"
            v-for="(item, index) in row.testsuites"
            :key="index"
            >{{ item.name }}</Tag
          >
        </template>
        <template slot-scope="{ row }" slot="modifier">{{
          row.modifier.real_name
        }}</template>
        <template slot-scope="{ row }" slot="level">
          <Select
            transfer
            v-model="row.level"
            @on-change="changeTestsuiteSetLevel(row)"
          >
            <div
              slot="prefix"
              size="small"
              :class="
                'levelSelect-prefix levelOption-' + row.level.toLowerCase()
              "
            ></div>
            <Option
              v-for="(item, index) in levels"
              :value="item.value"
              :label="item.label"
              :key="index"
              :class="'levelOption levelOption-' + item.value.toLowerCase()"
            ></Option>
          </Select>
        </template>
        <template slot-scope="{ row }" slot="status">
          <Icon size="24" :color="statusColor[row.status]" type="ios-leaf" />
        </template>
        <template slot-scope="{ row }" slot="action">
          <Button
            size="small"
            type="text"
            style="color: #2d8cf0"
            @click="showEditTestsuiteSetModal(row)"
            >编辑</Button
          >
          <Button
            size="small"
            type="text"
            style="color: #2d8cf0"
            @click="showOrganizeTestsuiteModal(row)"
            >场景集组织</Button
          >
        </template>
      </Table>
      <Page
        transfer
        :total="page.total"
        :current="page.current"
        :page-size="page.pageSize"
        :page-size-opts="page.pageSizeOpts"
        size="small"
        show-elevator
        show-sizer
        show-total
        prev-text="上一页"
        next-text="下一页"
        style="margin-top: 15px"
        @on-change="change"
        @on-page-size-change="pageSizeChange"
      />
    </Card>
    <TestsuiteSetCreate
      :createTestsuiteSet.sync="createTestsuiteSet"
      @initTestsuiteSetTable="search"
    ></TestsuiteSetCreate>
    <TestsuiteSetEdit
      :editTestsuiteSet.sync="editTestsuiteSet"
      @initTestsuiteSetTable="search"
      :testsuiteSet="testsuiteSet"
    ></TestsuiteSetEdit>
    <TestsuiteSet2Testsuite
      :organizeTestsuite.sync="organizeTestsuite"
      @initTestsuiteSetTable="search"
      :testsuiteSet.sync="testsuiteSet"
      :project.sync="project"
    ></TestsuiteSet2Testsuite>
    <PeriodicTaskCreate
      :createPeriodicTask.sync="createPeriodicTask"
      :task.sync="periodicTask"
      :args.sync="periodicTaskArgs"
      :showKwargs="false"
    ></PeriodicTaskCreate>
  </div>
</template>
<script>
import { getProjectNames } from "@/api/HttpAutoTestService/project";
import { getTestsuiteNames } from "@/api/HttpAutoTestService/testsuite";
import { getUserNames } from "@/api/HttpAutoTestService/user";
import {
  getTestsuiteSets,
  partialUpdateTestsuiteSet,
  batchDeleteTestsuiteSet,
  batchExecTestsuiteSet,
  exportTestsuiteSet,
} from "@/api/HttpAutoTestService/testsuite-set";
import TestsuiteSetCreate from "./testsuite-set-create";
import TestsuiteSetEdit from "./testsuite-set-edit";
import TestsuiteSet2Testsuite from "./testsuite-set2testsuite";
import PeriodicTaskCreate from "@/view/components/CeleryScheduledTaskService/periodic-task/periodic-task-create";
import CollapseTransition from "_c/collapse-transition/collapse-transition.js";
export default {
  name: "testsuite-set",
  components: {
    TestsuiteSetCreate,
    TestsuiteSetEdit,
    TestsuiteSet2Testsuite,
    PeriodicTaskCreate,
    CollapseTransition,
  },
  mounted() {
    this.searchParams.creator = [this.$store.state.user.id];
    this.search();
    // 获取项目
    this.getProjectNames();
    // 获取场景
    this.getTestsuiteNames();
    // 获取用户
    getUserNames()
      .then((res) => {
        this.users = res.data;
      })
      .catch((err) => {
        this.$Modal.error({
          title: "系统异常，请联系管理员……",
          content: JSON.stringify(err),
          closable: true,
        });
      });
  },
  data() {
    return {
      loading: false,
      showMore: false,
      createPeriodicTask: false,
      createTestsuiteSet: false,
      editTestsuiteSet: false,
      organizeTestsuite: false,
      periodicTask: "",
      periodicTaskArgs: "[]",
      statusColor: {
        INITIAL: "#2db7f5",
        PASS: "#19be6b",
        PARTIAL_PASS: "#ff9900",
        FAIL: "#ed4014",
      },
      searchParams: {
        name: "",
        project: "",
        testsuite: [],
        status: "",
        level: [],
        creator: [],
      },
      testsuiteSetColumns: [
        {
          type: "selection",
          width: 60,
          align: "center",
          fixed: "left",
        },
        {
          title: "场景集名称",
          key: "name",
          width: 350,
          tooltip: true,
        },
        {
          title: "所属项目",
          slot: "project",
          width: 350,
          ellipsis: true,
        },
        {
          title: "测试场景",
          slot: "testsuites",
          minWidth: 350,
        },
        {
          title: "最近维护人",
          slot: "modifier",
          align: "center",
          width: 120,
        },
        {
          title: "重要级别",
          slot: "level",
          align: "center",
          width: 120,
        },
        {
          title: "状态",
          slot: "status",
          align: "center",
          width: 65,
          fixed: "right",
        },
        {
          title: "操作",
          slot: "action",
          width: 170,
          align: "center",
          fixed: "right",
        },
      ],
      testsuiteSetData: [],
      levels: [
        { value: "LOW", label: "低" },
        { value: "NORMAL", label: "中" },
        { value: "HIGH", label: "高" },
        { value: "HIGHER", label: "更高" },
      ],
      project: {},
      projects: [],
      testsuites: [],
      testsuiteSet: {},
      selectedTestsuiteSets: [],
      users: [],
      page: {
        current: 1,
        total: 0,
        pageSize: 50,
        pageSizeOpts: [10, 30, 50, 100, 200],
      },
    };
  },
  methods: {
    search(page) {
      let data = {
        name: this.searchParams.name,
        project: this.searchParams.project,
        testsuite: this.searchParams.testsuite.toString(),
        status: this.searchParams.status,
        level: this.searchParams.level.toString(),
        creator: this.searchParams.creator.toString(),
        page: 1,
        page_size: this.page.pageSize,
      };
      if (typeof page == "number") {
        data.page = page;
      }
      this.page.current = data.page;

      getTestsuiteSets(data)
        .then((res) => {
          const data = res.data;
          this.testsuiteSetData = data.results;
          this.page.total = data.count;
          if (data.next === null) {
            this.page.current = Math.ceil(this.page.total / this.page.pageSize);
          }
          if (data.previous === null) {
            this.page.current = 1;
          }
        })
        .catch((err) => {
          this.$Modal.error({
            title: "系统异常，请联系管理员……",
            content: JSON.stringify(err),
            closable: true,
          });
        });
    },
    reset() {
      this.searchParams = {
        name: "",
        project: "",
        testsuite: [],
        status: "",
        level: [],
        creator: [],
      };
      this.getTestsuiteNames();
      this.search();
    },
    // 获取项目
    getProjectNames() {
      getProjectNames()
        .then((res) => {
          this.projects = res.data;
        })
        .catch((err) => {
          this.$Modal.error({
            title: "系统异常，请联系管理员……",
            content: JSON.stringify(err),
            closable: true,
          });
        });
    },
    // 获取场景
    getTestsuiteNames(project) {
      getTestsuiteNames({ project: project })
        .then((res) => {
          this.testsuites = res.data;
          if (Array.isArray(this.testsuites)) {
            let testsuiteIds = this.testsuites.map((item) => {
              return item.id;
            });
            let testsuite = this.searchParams.testsuite.filter((item) => {
              return testsuiteIds.includes(item);
            });
            this.searchParams.testsuite = testsuite;
          }
        })
        .catch((err) => {
          this.$Modal.error({
            title: "系统异常，请联系管理员……",
            content: JSON.stringify(err),
            closable: true,
          });
        });
    },
    showEditTestsuiteSetModal(row) {
      let data = {
        project: row.project ? row.project.id : "",
        hasTestsuite: row.testsuites.length > 0,
      };
      let { id, name, remark } = row;
      Object.assign(data, { id, name, remark });
      this.testsuiteSet = data;
      this.editTestsuiteSet = true;
    },
    selectionChange(val) {
      this.selectedTestsuiteSets = val.map((item) => {
        return item.id;
      });
    },
    showBatchDeleteTestsuiteSet() {
      let data = {
        testsuite_sets: this.selectedTestsuiteSets,
      };
      batchDeleteTestsuiteSet(data)
        .then((res) => {
          this.$Message.info("删除成功");
          this.search();
          this.selectedTestsuiteSets = [];
        })
        .catch((err) => {
          this.$Modal.error({
            title: "系统异常，请联系管理员……",
            content: JSON.stringify(err),
            closable: true,
          });
        });
    },
    // 更改场景集重要级别
    changeTestsuiteSetLevel(row) {
      const { id, level } = row;
      partialUpdateTestsuiteSet({ id, level })
        .then((res) => {
          if (res.status === 200) {
            this.$Message.info("修改成功");
          } else {
            this.$Message.error("修改失败");
          }
        })
        .catch((err) => {
          this.$Modal.error({
            title: "系统异常，请联系管理员……",
            content: JSON.stringify(err),
            closable: true,
          });
        });
    },
    // 显示场景集组织弹框
    showOrganizeTestsuiteModal(row) {
      let { id, name } = row;
      this.testsuiteSet = { id, name };
      this.project = row.project ? row.project : {};
      this.organizeTestsuite = true;
    },
    // 选择项目
    changeProjectOption(val) {
      let project = val.value;
      this.searchParams.project = project;
      this.getTestsuiteNames(project);
      this.search();
    },
    // 清空选择的项目
    clearProject() {
      this.searchParams.project = "";
      this.getTestsuiteNames();
      this.search();
    },
    // 批量执行测试场景集
    handleBatchExecTestsuiteSet() {
      if (this.selectedTestsuiteSets.length > 0) {
        let data = {
          testsuite_sets: this.selectedTestsuiteSets,
        };
        batchExecTestsuiteSet(data).then((res) => {
          this.$Message.info(res.data);
          this.search();
        });
        return;
      }
      this.$Message.info("请选择需要执行的场景集");
    },
    // 导出测试场景集
    handleExportTestsuiteSet() {
      if (this.selectedTestsuiteSets.length > 0) {
        let data = {
          testsuite_set_ids: this.selectedTestsuiteSets,
        };
        this.loading = true;
        exportTestsuiteSet(data)
          .then((res) => {
            let blob = new Blob([res.data], {
              type: "application/vnd.ms-excel",
            });
            const blobUrl = window.URL.createObjectURL(blob);
            const elementLink = document.createElement("a");
            elementLink.download = "测试场景集导出文档.xlsx";
            elementLink.style.display = "none";
            elementLink.href = blobUrl;
            // 触发点击
            document.body.appendChild(elementLink);
            elementLink.click();
            // 然后移除
            document.body.removeChild(elementLink);
            this.loading = false;
          })
          .catch((err) => {
            this.loading = false;
            this.$Message.info("导出场景失败，请重试……");
          });
        return;
      }
      this.$Message.info("请选择需要导出的场景");
    },
    showCreatePeriodicTaskModal() {
      this.periodicTask =
        "批量执行测试场景集:HttpAutoTestService.testsuite_set_task.batch_exec_testsuite_set";
      if (this.selectedTestsuiteSets.length > 0) {
        let temp = JSON.stringify(this.selectedTestsuiteSets).replace(
          /\"/g,
          "'"
        );
        this.periodicTaskArgs = `["${temp}"]`;
        this.createPeriodicTask = true;
        return;
      }
      this.$Message.info("请选择需要创建定时任务的场景");
    },
    change(val) {
      this.page.current = val;
      this.search(val);
    },
    pageSizeChange(val) {
      this.page.pageSize = val;
      this.search();
    },
  },
};
</script>
<style scoped>
.levelSelect-prefix {
  width: 15px;
  height: 15px;
  border-radius: 50%;
}
.levelOption {
  color: #fff;
}
.levelOption-low {
  background-color: #2db7f5;
}
.levelOption-normal {
  background-color: #19be6b;
}
.levelOption-high {
  background-color: #ff9900;
}
.levelOption-higher {
  background-color: #ed4014;
}
.ivu-form-item {
  width: 100%;
}
</style>